package com.platform.wx.mp.config;

import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.google.common.collect.Maps;
import com.platform.entity.MpMsgEntity;
import com.platform.service.MpMsgService;
import com.platform.wx.mp.handler.KfSessionHandler;
import com.platform.wx.mp.handler.LocationHandler;
import com.platform.wx.mp.handler.LogHandler;
import com.platform.wx.mp.handler.MenuHandler;
import com.platform.wx.mp.handler.MsgHandler;
import com.platform.wx.mp.handler.NullHandler;
import com.platform.wx.mp.handler.ScanHandler;
import com.platform.wx.mp.handler.StoreCheckNotifyHandler;
import com.platform.wx.mp.handler.SubscribeHandler;
import com.platform.wx.mp.handler.UnsubscribeHandler;

import me.chanjar.weixin.common.api.WxConsts.EventType;
import me.chanjar.weixin.common.api.WxConsts.MenuButtonType;
import me.chanjar.weixin.common.api.WxConsts.XmlMsgType;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import me.chanjar.weixin.mp.constant.WxMpEventConstants;

/**
 * wechat mp configuration
 *
 * @author Binary Wang(https://github.com/binarywang)
 */
@Component
public class WxMpConfiguration {
	
    @Autowired
    private MpMsgService mpMsgService;

    @Autowired
    private LogHandler logHandler;
    @Autowired
    private NullHandler nullHandler;
    @Autowired
    private KfSessionHandler kfSessionHandler;
    @Autowired
    private StoreCheckNotifyHandler storeCheckNotifyHandler;
    @Autowired
    private LocationHandler locationHandler;
    @Autowired
    private MenuHandler menuHandler;
    @Autowired
    private MsgHandler msgHandler;
    @Autowired
    private UnsubscribeHandler unsubscribeHandler;
    @Autowired
    private SubscribeHandler subscribeHandler;
    @Autowired
    private ScanHandler scanHandler;

    private Map<Integer, WxMpMessageRouter> routers = Maps.newHashMap();
    private Map<Integer, WxMpService> mpServices = Maps.newHashMap();

//    @Autowired
//    public WxMpConfiguration(LogHandler logHandler, NullHandler nullHandler, KfSessionHandler kfSessionHandler,
//                             StoreCheckNotifyHandler storeCheckNotifyHandler, LocationHandler locationHandler,
//                             MenuHandler menuHandler, MsgHandler msgHandler, UnsubscribeHandler unsubscribeHandler,
//                             SubscribeHandler subscribeHandler, ScanHandler scanHandler) {
//        this.logHandler = logHandler;
//        this.nullHandler = nullHandler;
//        this.kfSessionHandler = kfSessionHandler;
//        this.storeCheckNotifyHandler = storeCheckNotifyHandler;
//        this.locationHandler = locationHandler;
//        this.menuHandler = menuHandler;
//        this.msgHandler = msgHandler;
//        this.unsubscribeHandler = unsubscribeHandler;
//        this.subscribeHandler = subscribeHandler;
//        this.scanHandler = scanHandler;
//    }

//    public Map<Integer, WxMpMessageRouter> getRouters() {
//        return routers;
//    }
//
//    public Map<Integer, WxMpService> getMpServices() {
//        return mpServices;
//    }

    public WxMpService getMpService(Integer appId) {
    	WxMpService wxMapService = mpServices.get(appId);
    	if(wxMapService == null) {
    		MpMsgEntity mpMsg = mpMsgService.queryObject(appId);
    		wxMapService = putWxmpService(mpMsg);
    	}
    	return wxMapService;
    }
    
	@PostConstruct
    public void init() {
    	Map<String, Object> params = Maps.newHashMap();
    	params.put("type", 1);
    	List<MpMsgEntity> mpMsgs = mpMsgService.queryList(params);
    	for(MpMsgEntity mpMsg:mpMsgs) {
    		putWxmpService(mpMsg);
        }
    }

    public WxMpService putWxmpService(MpMsgEntity mpMsg) {
    	WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl();
        configStorage.setAppId(mpMsg.getAppId());
        configStorage.setSecret(mpMsg.getMpSecret());
        configStorage.setToken(mpMsg.getToken());
        configStorage.setAesKey(mpMsg.getAesKey());

        WxMpService service = new WxMpServiceImpl();
        service.setWxMpConfigStorage(configStorage);
        routers.put(mpMsg.getId(), this.newRouter(service));
        mpServices.put(mpMsg.getId(), service);
        return service;
    }
    
    private WxMpMessageRouter newRouter(WxMpService wxMpService) {
        final WxMpMessageRouter newRouter = new WxMpMessageRouter(wxMpService);
        // 记录所有事件的日志 （异步执行）
        newRouter.rule().handler(this.logHandler).next();

        // 接收客服会话管理事件
        newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
            .event(WxMpEventConstants.CustomerService.KF_CREATE_SESSION)
            .handler(this.kfSessionHandler).end();
        newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
            .event(WxMpEventConstants.CustomerService.KF_CLOSE_SESSION)
            .handler(this.kfSessionHandler)
            .end();
        newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
            .event(WxMpEventConstants.CustomerService.KF_SWITCH_SESSION)
            .handler(this.kfSessionHandler).end();

        // 门店审核事件
        newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
            .event(WxMpEventConstants.POI_CHECK_NOTIFY)
            .handler(this.storeCheckNotifyHandler).end();

        // 自定义菜单事件
        newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
            .event(MenuButtonType.CLICK).handler(this.menuHandler).end();

        // 点击菜单连接事件
        newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
            .event(MenuButtonType.VIEW).handler(this.nullHandler).end();

        // 关注事件
        newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
            .event(EventType.SUBSCRIBE).handler(this.subscribeHandler)
            .end();

        // 取消关注事件
        newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
            .event(EventType.UNSUBSCRIBE)
            .handler(this.unsubscribeHandler).end();

        // 上报地理位置事件
        newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
            .event(EventType.LOCATION).handler(this.locationHandler)
            .end();

        // 接收地理位置消息
        newRouter.rule().async(false).msgType(XmlMsgType.LOCATION)
            .handler(this.locationHandler).end();

        // 扫码事件
        newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
            .event(EventType.SCAN).handler(this.scanHandler).end();

        // 默认
        newRouter.rule().async(false).handler(this.msgHandler).end();

        return newRouter;
    }

}
